<!DOCTYPE html>
<html>
  <head>
    <title>WebSocket聊天测试 V2</title>
    <script src="https://cdn.socket.io/4.7.4/socket.io.min.js"></script>
    <style>
      .chat-container {
        display: flex;
        width: 1000px;
        margin: 20px auto;
      }
      .left-panel {
        width: 200px;
        margin-right: 20px;
      }
      .main-panel {
        flex: 1;
      }
      .message-container {
        height: 400px;
        border: 1px solid #ccc;
        overflow-y: auto;
        padding: 10px;
        margin-bottom: 10px;
      }
      .message {
        margin: 5px 0;
        padding: 5px;
        border-radius: 5px;
      }
      .sent {
        background-color: #e3f2fd;
        margin-left: 50px;
      }
      .received {
        background-color: #f5f5f5;
        margin-right: 50px;
      }
      .recalled {
        color: #999;
        font-style: italic;
      }
      .user-list {
        border: 1px solid #ccc;
        padding: 10px;
        margin-bottom: 10px;
      }
      .user-item {
        padding: 5px;
        cursor: pointer;
      }
      .user-item:hover {
        background-color: #f0f0f0;
      }
      .online {
        color: green;
      }
      .offline {
        color: gray;
      }
      .unread-badge {
        background-color: red;
        color: white;
        border-radius: 50%;
        padding: 2px 6px;
        font-size: 12px;
        margin-left: 5px;
      }
      .controls {
        margin-top: 10px;
      }
      .status {
        margin-top: 10px;
        color: #666;
      }
      .search-box {
        display: flex;
        gap: 5px;
        margin-bottom: 10px;
      }
      .search-box input {
        flex: 1;
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 4px;
      }
      .search-box button {
        padding: 5px 10px;
        background-color: #4caf50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }
      .search-box button:hover {
        background-color: #45a049;
      }
    </style>
  </head>
  <body>
    <div class="chat-container">
      <div class="left-panel">
        <div>
          <input
            type="text"
            id="token"
            placeholder="输入token"
            style="width: 180px"
          />
          <button onclick="connect()">连接</button>
          <button onclick="disconnect()">断开</button>
        </div>
        <div class="user-list">
          <h3>用户列表</h3>
          <div class="search-box" style="display: flex; margin-bottom: 10px">
            <input
              type="text"
              id="searchInput"
              placeholder="输入用户名或学号..."
              style="flex: 1"
            />
            <button onclick="searchUsers()" id="searchButton" disabled>
              搜索
            </button>
          </div>
          <div id="onlineUsers"></div>
        </div>
        <div class="status">
          <div>未读消息: <span id="unreadCount">0</span></div>
          <div>当前状态: <span id="connectionStatus">未连接</span></div>
        </div>
      </div>
      <div class="main-panel">
        <div>当前聊天对象: <span id="currentReceiver">未选择</span></div>
        <div class="message-container" id="messages"></div>
        <div class="controls">
          <input
            type="text"
            id="messageInput"
            placeholder="输入消息"
            style="width: 70%"
          />
          <button onclick="sendMessage()">发送</button>
          <button onclick="loadMoreHistory()">加载更多历史消息</button>
        </div>
      </div>
    </div>

    <script>
      let socket;
      let currentReceiverId = "";
      let currentReceiverName = "";
      let historySkip = 0;
      const HISTORY_LIMIT = 20;

      const messagesDiv = document.getElementById("messages");
      const messageInput = document.getElementById("messageInput");
      const onlineUsersList = document.getElementById("onlineUsers");
      const unreadCountSpan = document.getElementById("unreadCount");
      const connectionStatusSpan = document.getElementById("connectionStatus");
      const currentReceiverSpan = document.getElementById("currentReceiver");

      function connect() {
        const token = document.getElementById("token").value;
        if (!token) {
          alert("请输入token");
          return;
        }

        socket = io("http://localhost:3000", {
          auth: { token },
        });

        socket.on("connect", () => {
          console.log("WebSocket连接成功");
          connectionStatusSpan.textContent = "已连接";
          console.log("正在获取用户列表...");
          socket.emit("getAllUsers");
          socket.emit("getUnreadCount");
          document.getElementById("searchButton").disabled = false;
        });

        socket.on("connect_error", (error) => {
          addMessage("系统", "连接错误: " + error.message);
          connectionStatusSpan.textContent = "连接错误";
        });

        socket.on("newMessage", (data) => {
          addMessage(
            data.sender.username,
            data.content,
            "received",
            data.messageId
          );
          if (!data.isRead) {
            socket.emit("markAsRead", { messageId: data.messageId });
          }
        });

        socket.on("messageSent", (response) => {
          if (response.success) {
            addMessage(
              "我",
              response.message.content,
              "sent",
              response.message.messageId
            );
          } else {
            addMessage("系统", "发送失败: " + response.error, "error");
          }
        });

        socket.on("messageRead", (data) => {
          const messageElement = document.querySelector(
            `[data-message-id="${data.messageId}"]`
          );
          if (messageElement) {
            messageElement.querySelector(".read-status").textContent = "已读";
          }
        });

        socket.on("messageRecalled", (data) => {
          const messageElement = document.querySelector(
            `[data-message-id="${data.messageId}"]`
          );
          if (messageElement) {
            messageElement.classList.add("recalled");
            messageElement.textContent = "消息已撤回";
          }
        });

        socket.on("userOnline", (data) => {
          addMessage("系统", `${data.username} 上线了`);
          updateUserList();
        });

        socket.on("userOffline", (data) => {
          addMessage("系统", `${data.username} 下线了`);
          updateUserList();
        });

        socket.on("usersList", (users) => {
          console.log("收到用户列表:", users);
          if (!Array.isArray(users)) {
            console.error("接收到的用户列表格式不正确");
            return;
          }
          updateUserList(users);
        });

        socket.on("unreadCount", (data) => {
          unreadCountSpan.textContent = data.count;
        });

        socket.on("historyMessages", (data) => {
          if (data.success) {
            data.messages.reverse().forEach((msg) => {
              const type =
                msg.sender._id === socket.userInfo?.userId
                  ? "sent"
                  : "received";
              addMessage(
                type === "sent" ? "我" : msg.sender.username,
                msg.content,
                type,
                msg._id,
                msg.isRead,
                true
              );
            });
          }
        });

        socket.on("searchResults", (users) => {
          console.log("收到搜索结果:", users);
          updateUserList(users);
        });

        socket.on("error", (error) => {
          console.error("服务器错误:", error);
          addMessage("系统", `错误: ${error.message}`, "error");
        });
      }

      function disconnect() {
        if (socket) {
          socket.disconnect();
          connectionStatusSpan.textContent = "未连接";
          onlineUsersList.innerHTML = "";
          messagesDiv.innerHTML = "";
          currentReceiverId = "";
          currentReceiverName = "";
          currentReceiverSpan.textContent = "未选择";
          document.getElementById("searchButton").disabled = true;
        }
      }

      function selectReceiver(userId, username) {
        currentReceiverId = userId;
        currentReceiverName = username;
        currentReceiverSpan.textContent = username;
        messagesDiv.innerHTML = "";
        historySkip = 0;
        loadHistory();
      }

      function loadHistory() {
        if (currentReceiverId) {
          socket.emit("getHistory", {
            otherUserId: currentReceiverId,
            limit: HISTORY_LIMIT,
            skip: historySkip,
          });
        }
      }

      function loadMoreHistory() {
        historySkip += HISTORY_LIMIT;
        loadHistory();
      }

      function sendMessage() {
        if (!socket || !socket.connected) {
          alert("请先连接");
          return;
        }

        if (!currentReceiverId) {
          alert("请先选择聊天对象");
          return;
        }

        const content = messageInput.value.trim();
        if (!content) {
          alert("请输入消息内容");
          return;
        }

        socket.emit("sendMessage", {
          receiverId: currentReceiverId,
          content: content,
        });

        messageInput.value = "";
      }

      function addMessage(
        sender,
        content,
        type = "",
        messageId = null,
        isRead = false,
        prepend = false
      ) {
        const messageDiv = document.createElement("div");
        messageDiv.className = `message ${type}`;
        if (messageId) {
          messageDiv.setAttribute("data-message-id", messageId);
        }

        const messageContent = document.createElement("div");
        messageContent.textContent = `${sender}: ${content}`;
        messageDiv.appendChild(messageContent);

        if (type === "sent") {
          const readStatus = document.createElement("span");
          readStatus.className = "read-status";
          readStatus.textContent = isRead ? "已读" : "未读";
          messageDiv.appendChild(readStatus);
        }

        if (prepend && messagesDiv.firstChild) {
          messagesDiv.insertBefore(messageDiv, messagesDiv.firstChild);
        } else {
          messagesDiv.appendChild(messageDiv);
          messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }
      }

      function updateUserList(users = []) {
        console.log("开始更新用户列表, 数量:", users.length);
        onlineUsersList.innerHTML = "";

        if (!Array.isArray(users)) {
          console.error("用户列表不是数组");
          onlineUsersList.innerHTML =
            '<div class="user-item">获取用户列表失败</div>';
          return;
        }

        if (users.length === 0) {
          onlineUsersList.innerHTML =
            '<div class="user-item">没有找到用户</div>';
          return;
        }

        users.forEach((user) => {
          if (user.userId && user.username) {
            const userDiv = document.createElement("div");
            userDiv.className = `user-item ${
              user.status === "online" ? "online" : "offline"
            }`;
            const displayText = [
              user.username,
              user.studentId ? `(${user.studentId})` : "",
              user.status,
            ]
              .filter(Boolean)
              .join(" - ");
            userDiv.textContent = displayText;
            userDiv.onclick = () => selectReceiver(user.userId, user.username);
            onlineUsersList.appendChild(userDiv);
          } else {
            console.warn("无效的用户数据:", user);
          }
        });
      }

      function searchUsers() {
        const searchInput = document.getElementById("searchInput").value.trim();
        console.log("发起搜索:", searchInput);

        if (!socket || !socket.connected) {
          alert("请先连接服务器");
          return;
        }

        if (!searchInput) {
          console.log("搜索词为空，获取所有用户");
          socket.emit("getAllUsers");
          return;
        }

        socket.emit("searchUsers", { keyword: searchInput });
      }

      // 支持按Enter发送消息
      messageInput.addEventListener("keypress", (e) => {
        if (e.key === "Enter") {
          sendMessage();
        }
      });

      // 修改回车键行为
      document
        .getElementById("searchInput")
        .addEventListener("keypress", (e) => {
          if (e.key === "Enter") {
            searchUsers();
          }
        });
    </script>
  </body>
</html>
